package com.histone.lib_download.downloader;

import android.content.Context;
import android.util.Log;

import com.histone.lib_download.DownloadFactory;
import com.histone.lib_download.contract.DownloadTakeNotes;
import com.histone.lib_download.contract.IDownloadProgress;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;


/**
 * @author robin
 * @version v1.0 [2020/6/11]
 * <p>
 * 下载执行者
 */
public class Downloader {
    private Context mContext;
    private FileInfo fileInfo;
    private int threadCount = 1;
    public boolean isPause = false;
    private List<DownloadThread> downloadThreads;
    private IDownloadProgress loadPress;

    /**
     * @param mContext 上下文
     * @param fileInfo 文件信息
     */
    public Downloader(Context mContext, FileInfo fileInfo) {
        this.mContext = mContext;
        this.fileInfo = fileInfo;
//        if (fileInfo.fileLength < (1024 * 1024 * 10)) {
//            //小于10M，自动启动两个线程
//            threadCount = 2;
//        } else {
//            threadCount = 3;
//        }
    }

    /**
     * @param mContext    上下文
     * @param fileInfo    文件信息
     * @param threadCount 开几个线程
     */
    public Downloader(Context mContext, FileInfo fileInfo, int threadCount) {
        this.mContext = mContext;
        this.fileInfo = fileInfo;
        this.threadCount = threadCount;
    }

    public void download(IDownloadProgress loadPress) {
        this.loadPress = loadPress;

        ThreadInfo threadInfo = new ThreadInfo(1, fileInfo.downloadUrl, 0, fileInfo.fileLength, fileInfo.finishLength);
        //启动
        DownloadThread downloadThread = new DownloadThread(threadInfo);
        DownloadFactory.runOnAsync(downloadThread);
    }

    class DownloadThread extends Thread {
        private final ThreadInfo threadInfo;
        public boolean isFinished = false;
        private InputStream inputStream;


        public DownloadThread(ThreadInfo threadInfo) {
            this.threadInfo = threadInfo;
        }

        @Override
        public void run() {
            super.run();
            HttpURLConnection huc = null;
            RandomAccessFile randomAccessFile = null;

            try {
                URL url = new URL(threadInfo.url);
                huc = (HttpURLConnection) url.openConnection();
                huc.setConnectTimeout(5000);
                huc.setRequestMethod("GET");
                //下载位置(断点续传关键点)
                long start = threadInfo.thread_start + threadInfo.finished;
                huc.setRequestProperty("Range", "bytes=" + start + "-" + threadInfo.thread_end);
                File dir = new File(fileInfo.localFilePath);
                if (!dir.exists()) {
                    dir.mkdirs();
                }
                File file = new File(dir, fileInfo.fileName);
                //初次下载，存在相同问题
                if (file.exists() && file.isFile() && fileInfo.finishLength == 0) {
                    boolean delete = file.delete();
                    Log.e("DownloadService", "删除旧文件:" + file.getName());
                }
                randomAccessFile = new RandomAccessFile(file, "rwd");
                randomAccessFile.seek(start);

                if (huc.getResponseCode() == HttpURLConnection.HTTP_PARTIAL) { //注意 不是 200
                    //记录已下载
                    DownloadTakeNotes.getInstance().save(threadInfo.url, fileInfo.fileName, fileInfo.localFilePath, fileInfo.fileLength, threadInfo.finished);
                    inputStream = huc.getInputStream();
                    byte[] bytes = new byte[1024 * 4];
                    int len = -1;
                    while ((len = inputStream.read(bytes)) != -1) {
                        randomAccessFile.write(bytes, 0, len);
                        threadInfo.finished = threadInfo.finished + len;
                        onNotificationProgress(threadInfo.finished);
                        if (isPause) {
                            //记录已下载
                            DownloadTakeNotes.getInstance().update(threadInfo.finished, fileInfo.fileLength);
                            break;
                        }
                    }
                    isFinished = true;
                    if (loadPress != null) {
                        loadPress.onDownloadSuccess(fileInfo);
                    }
                }
            } catch (Exception e) {
                Log.e("DownloadService", e.toString());
                //记录已下载
                if (loadPress != null) loadPress.onDownloadError(e);
                DownloadTakeNotes.getInstance().update(threadInfo.finished, fileInfo.fileLength);
            } finally {
                try {
                    if (randomAccessFile != null)
                        randomAccessFile.close();
                    if (inputStream != null)
                        inputStream.close();
                    if (huc != null)
                        huc.disconnect();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }


    }


    //更新进度
    private synchronized void onNotificationProgress(long len) {
        if (loadPress != null) {
            loadPress.onAsyncProgress(len, fileInfo.fileLength);
        }
    }

    //检查所有线程是否完毕
    private synchronized void isAllThreadFinished() {
        boolean iaAllFinished = true;
        for (DownloadThread thread : downloadThreads) {
            if (!thread.isFinished) {
                iaAllFinished = false;
                break;
            }
        }
    }
}
